﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms.DataVisualization.Charting;
using Kangaroo.Model;
using System.Drawing;
using Steema.TeeChart;
using Steema.TeeChart.Styles;
using Axis = Steema.TeeChart.Axis;

namespace Kangaroo.Shell
{
    public partial class Main
    {
        private void InitializeChartControls()
        {
            IntializeSpectrumChartControls(ref P_QChart);
            P_QChart.Text = P_QChart.Header.Text = "最大放电量相位分布";

            P_QChart.Axes.Bottom.Title.Text = "相位 / 度";
            P_QChart.Axes.Left.Title.Text = "幅值 / %";
            P_QChart.Axes.Bottom.Increment = 180;
            P_QChart.Axes.Bottom.Maximum = 360;
            P_QChart.Axes.Bottom.Minimum = 0;

            IntializeSpectrumChartControls(ref T_NChart);
            T_NChart.Text = T_NChart.Header.Text = "放电次数周期分布";

            T_NChart.Axes.Bottom.Title.Text = "周期 / s";
            T_NChart.Axes.Left.Title.Text = "重复率 / 次数";
            T_NChart.Axes.Left.Increment = 1;

            IntializeSpectrumChartControls(ref T_QChart);
            T_QChart.Text = T_QChart.Header.Text = "最大放电量周期分布";

            T_QChart.Axes.Bottom.Title.Text = "周期 / s";
            T_QChart.Axes.Left.Title.Text = "幅值 / %";

            IntializeSpectrumChartControls(ref Q_NChart);
            Q_NChart.Text = Q_NChart.Header.Text = "放电能量分布";

            Q_NChart.Axes.Bottom.Title.Text = "能量";
            Q_NChart.Axes.Left.Title.Text = "重复率 / 次数";

            prpsChart.MaxValue = new PDChart.XYZ(50, 60, 1);
            prpsChart.BackColor = Color.White;
            prpsChart.LineColor = Color.Gray;
            prpsChart.Label.Color = Color.Black;
            prpsChart.Title.Color = Color.Blue;
            prpsChart.Title.Text = "PRPS图谱";

            prpsChart.Zoom.BackColor = Color.LightGray;
            prpsChart.Zoom.Color = Color.Black;
            prpsChart.Zoom.Font = new Font("黑体", 12);

            prpsChart.FootNote.Color = Color.White;
            prpsChart.FootNote.Font = new Font("黑体", 10);
            prpsChart.BorderColor = Color.Black;


            // 最大放电量趋势图
            InitializeTrendingChartControls(ref maxQTrendingTChart);
            maxQTrendingTChart.Text = maxQTrendingTChart.Header.Text = "统计参数 MaxQ (%)";            

            // 平均放电量趋势图
            InitializeTrendingChartControls(ref avgQTrendingTChart);
            avgQTrendingTChart.Text = avgQTrendingTChart.Header.Text = "统计参数 AvgQ (%)";

            // 最大放电相位趋势图
            InitializeTrendingChartControls(ref pdPhaseTrendingTChart);
            pdPhaseTrendingTChart.Text = pdPhaseTrendingTChart.Header.Text = "统计参数 Phase";

            // 放电次数趋势图
            InitializeTrendingChartControls(ref pdCountTrendingTChart);
            pdCountTrendingTChart.Text = pdCountTrendingTChart.Header.Text = "局放脉冲个数";

            InitializeSummaryChart(summaryChart);
        }

        private static void AdjustAxisMax(Axis axis)
        {
            var m = (axis.MinYValue + axis.MaxYValue) / 2;
            var s = (axis.MaxYValue - axis.MinYValue) / 2;
            axis.SetMinMax(axis.MinYValue, m + 2 * s);
        }

        private static void AdjustAxisMinMax(Axis axis)
        {
            var m = (axis.MinYValue + axis.MaxYValue) / 2;
            var s = (axis.MaxYValue - axis.MinYValue) / 2;
            axis.SetMinMax(m - 2 * s, m + 2 * s);
        }

        private void IntializeSpectrumChartControls(ref TChart tChart)
        {
            if(tChart == null)
                return;

            IntializeBaseChartControls(ref tChart);

            Steema.TeeChart.Styles.Bar bar = new Steema.TeeChart.Styles.Bar();
            InitBar(bar, Color.Blue, false, Steema.TeeChart.Styles.BarStyles.Rectangle, 50);

            tChart.Series.Add(bar);
        }

        private void InitializeSummaryChart(TChart tChart)
        {
            if(tChart == null)
                return;

            tChart.Axes.Bottom.Labels.Separation = 30;

            tChart.Series.Clear();

            tChart.BackColor = Color.White;

            tChart.Aspect.View3D = false;
            tChart.Graphics3D.UseBuffer = true;

            tChart.Walls.Visible = true;// false;//////
            tChart.Zoom.MinPixels = 2;


            tChart.Panel.MarginBottom = 3;
            tChart.Panel.MarginTop = 3;

            tChart.Axes.Left.RelativePosition = 0;
            tChart.Axes.Left.PositionUnits = Steema.TeeChart.PositionUnits.Pixels;
            tChart.Axes.Left.AxisPen.Width = 1;
            tChart.Axes.Left.Automatic = false; /////
            tChart.Axes.Left.Title.CustomSize = 5;

            tChart.Axes.Bottom.Automatic = true;
            tChart.Axes.Bottom.PositionUnits = Steema.TeeChart.PositionUnits.Pixels;

            tChart.Axes.Bottom.Labels.RoundFirstLabel = true;
            tChart.Axes.Bottom.Labels.OnAxis = true;
            tChart.Axes.Bottom.AxisPen.Width = 1;

            tChart.Legend.Alignment = LegendAlignments.Bottom;

            tChart.Series.Add(InitBar(new HorizBar(), Color.Blue, false, Steema.TeeChart.Styles.BarStyles.Rectangle, 50));
            tChart.Series.Add(InitBar(new HorizBar(), Color.Green, false, Steema.TeeChart.Styles.BarStyles.Rectangle, 50));
            tChart.Series.Add(InitBar(new HorizBar(), Color.Red, false, Steema.TeeChart.Styles.BarStyles.Rectangle, 50));
            tChart.Series.Add(InitBar(new HorizBar(), Color.Cyan, false, Steema.TeeChart.Styles.BarStyles.Rectangle, 50));

            tChart.Text = tChart.Header.Text = "统计数据";

            tChart.Axes.Bottom.Title.Text = "百分比 / %";
            tChart.Axes.Bottom.Increment = 1;
            tChart.Axes.Bottom.Maximum = 100;
            tChart.Axes.Bottom.Minimum = 0;
            tChart.Axes.Left.Increment = 1;
            tChart.Axes.Left.Maximum = 4;
            tChart.Axes.Left.Minimum = 1;
            tChart.Axes.Left.Visible = false;

            tChart.Axes.Bottom.Automatic = false;/////
            tChart.Axes.Left.Automatic = false;/////
            tChart.Axes.Bottom.PositionUnits = PositionUnits.Percent;

        }

        private void IntializeBaseChartControls(ref TChart tChart)
        {
            tChart.Axes.Bottom.Labels.Separation = 30;

            tChart.Series.Clear();

            tChart.BackColor = Color.White;

            tChart.Aspect.View3D = false;
            tChart.Graphics3D.UseBuffer = true;

            tChart.Walls.Visible = true;
            tChart.Zoom.MinPixels = 2;


            tChart.Panel.MarginBottom = 3;
            tChart.Panel.MarginTop = 3;

            tChart.Axes.Left.RelativePosition = 0;
            tChart.Axes.Left.PositionUnits = Steema.TeeChart.PositionUnits.Pixels;
            tChart.Axes.Left.AxisPen.Width = 1;
            tChart.Axes.Left.Automatic = false; /////
            tChart.Axes.Left.Title.CustomSize = 5;

            tChart.Axes.Bottom.Automatic = true;
            tChart.Axes.Bottom.PositionUnits = Steema.TeeChart.PositionUnits.Pixels;

            tChart.Axes.Bottom.Labels.RoundFirstLabel = true;
            tChart.Axes.Bottom.Labels.OnAxis = true;
            tChart.Axes.Bottom.AxisPen.Width = 1;

            tChart.Legend.Visible = false;
        }

        private void InitBar(Steema.TeeChart.Styles.Bar bar, Color color, bool markVisible, Steema.TeeChart.Styles.BarStyles barStyle, int barWidthPercent)
        {
            bar.Color = color;
            bar.Marks.Visible = markVisible;
            bar.BarStyle = barStyle;
            bar.BarWidthPercent = barWidthPercent;     // 调整宽度,直线或柱状
        }

        private HorizBar InitBar(Steema.TeeChart.Styles.HorizBar bar, Color color, bool markVisible, Steema.TeeChart.Styles.BarStyles barStyle, int barWidthPercent)
        {
            bar.Color = color;
            bar.Marks.Visible = markVisible;
            bar.BarStyle = barStyle;
            return bar;
        }

        private void InitializeTrendingChartControls(ref TChart tChart)
        {
            if(tChart == null)
                return;

            IntializeBaseChartControls(ref tChart);
            FastLine fastLine1 = new FastLine();
            InitFastLine(fastLine1, Color.Red);
            tChart.Series.Add(fastLine1);
            FastLine fastLine2 = new FastLine();
            InitFastLine(fastLine2, Color.Blue);
            tChart.Series.Add(fastLine2);
            FastLine fastLine3 = new FastLine();
            InitFastLine(fastLine3, Color.Green);
            tChart.Series.Add(fastLine3);
            for(var i = 0; i < 3; i++)
            {
                tChart.Series[i].XValues.DateTime = true;
            }
        }

        private void InitFastLine(FastLine fastLine, Color color)
        {
            fastLine.Color = color;
        }

        private void InitializeTrendingChartControls(ref System.Windows.Forms.DataVisualization.Charting.Chart chart)
        {
            if(chart == null)
                return;
            chart.ChartAreas.Add("chtArea");
            chart.ChartAreas[0].BorderDashStyle = ChartDashStyle.Solid;
            chart.Series.Add("Single");
            chart.Series[0].ChartType = SeriesChartType.FastLine;
            chart.Series[0].Color = Color.Red;
            chart.Series.Add("Daily");
            chart.Series[1].ChartType = SeriesChartType.FastLine;
            chart.Series[1].Color = Color.Green;
            chart.Series.Add("Monthly");
            chart.Series[2].ChartType = SeriesChartType.FastLine;
            chart.Series[2].Color = Color.Blue;
        }

        private void GenerateCharacteristicSpectrum(SignalInfo signal)
        {
            var prpsGraph = signal.PrpsGraph;
            P_QChart.Series[0].Add(prpsGraph.PhaseRange, prpsGraph.MaxQPerPhase.Select(m => m * 100).ToArray());
            if(prpsGraph.MaxQPerPhase.Length > 0)
            {
                P_QChart.Axes.Left.SetMinMax(0, 100);
            }

            T_NChart.Series[0].Add(prpsGraph.PeriodRange, prpsGraph.PDCountPerPeriod);
            if(prpsGraph.PDCountPerPeriod.Length > 0)
            {
                AdjustAxisMax(T_NChart.Axes.Left);
            }

            T_QChart.Series[0].Add(prpsGraph.PeriodRange, prpsGraph.MaxQPerPeriod.Select(m => m * 100).ToArray());
            if(prpsGraph.MaxQPerPeriod.Length > 0)
            {
                T_QChart.Axes.Left.SetMinMax(0, 100);
            }

            Q_NChart.Series[0].Add(prpsGraph.PDRange, prpsGraph.PDCountPerPDRange);
            if(prpsGraph.PDCountPerPDRange.Length > 0)
            {
                AdjustAxisMax(Q_NChart.Axes.Left);
            }

            double[,] data = ConvertToDoubleArray(prpsGraph.Data, prpsGraph.Header.XSize, prpsGraph.Header.YSize);
            prpsChart.FootNote.Text = string.Format("{0}({1}%)", signal.PdTypeInfo.Type, signal.PdTypeInfo.Percentage * 100);
            prpsChart.Set(data);
            
            summaryChart.Series[0].Clear();
            summaryChart.Series[0].Add(signal.PdMax * 100, 1);
            summaryChart.Series[0].Title = string.Format("最大放电量 {0}%", signal.PdMax * 100);
            summaryChart.Series[1].Clear();
            summaryChart.Series[1].Add(signal.PdMean * 100, 2);
            summaryChart.Series[1].Title = string.Format("平均放电量 {0}%", signal.PdMean * 100);
            summaryChart.Series[2].Clear();
            summaryChart.Series[2].Add(signal.PdPhase / 3.6, 3);
            summaryChart.Series[2].Title = string.Format("放电相位(°) {0}", signal.PdPhase);
            summaryChart.Series[3].Clear();
            summaryChart.Series[3].Add(signal.PdRep / 30, 4);
            summaryChart.Series[3].Title = string.Format("放电频次(n) {0}", signal.PdRep);
            summaryChart.Axes.Bottom.SetMinMax(0, 100);
        }

        private double[,] ConvertToDoubleArray(float[,] p, int rowCount, int columnCount)
        {
            double[,] data = new double[rowCount, columnCount];
            for (var i = 0; i < columnCount; i++)
            {
                for (var j = 0; j < rowCount; j++)
                {
                    data[j, i] = (double)p[j, i];
                }
            }
            return data;
        }

        private void GenerateHistoricalTrandingChart(IEnumerable<SignalInfo> signalInfos)
        {
            if(signalInfos == null)
            {
                return;
            }

            var pdTime = signalInfos.Select(s => s.PdTime).ToList();
            var pdMaxs = signalInfos.Select(s => s.PdMax).ToList();
            var pdMeans = signalInfos.Select(s => s.PdMean).ToList();
            var pdPhases = signalInfos.Select(s => s.PdPhase).ToList();
            var pdReps = signalInfos.Select(s => s.PdRep).ToList();

            // 最大放电量趋势图
            maxQTrendingTChart.Series[0].Add(pdTime.ToArray(), pdMaxs.Select(p => p * 100).ToArray());
            maxQTrendingTChart.Series[1].Add(pdTime.ToArray(), GetStatisticData(pdMaxs, pdTime, 1).Select(p => p * 100).ToArray());
            maxQTrendingTChart.Series[2].Add(pdTime.ToArray(), GetStatisticData(pdMaxs, pdTime, 30).Select(p => p * 100).ToArray());
            maxQTrendingTChart.Axes.Left.SetMinMax(0, 100);

            // 平均放电量趋势图
            avgQTrendingTChart.Series[0].Add(pdTime.ToArray(), pdMeans.Select(p => p * 100).ToArray());
            avgQTrendingTChart.Series[1].Add(pdTime.ToArray(), GetStatisticData(pdMeans, pdTime, 1).Select(p => p * 100).ToArray());
            avgQTrendingTChart.Series[2].Add(pdTime.ToArray(), GetStatisticData(pdMeans, pdTime, 30).Select(p => p * 100).ToArray());
            avgQTrendingTChart.Axes.Left.SetMinMax(0, 100);

            // 最大放电相位趋势图
            pdPhaseTrendingTChart.Series[0].Add(pdTime.ToArray(), pdPhases.ToArray());
            pdPhaseTrendingTChart.Series[1].Add(pdTime.ToArray(), GetStatisticData(pdPhases, pdTime, 1).ToArray());
            pdPhaseTrendingTChart.Series[2].Add(pdTime.ToArray(), GetStatisticData(pdPhases, pdTime, 30).ToArray());
            AdjustAxisMinMax(pdPhaseTrendingTChart.Axes.Left);

            // 放电次数趋势图
            pdCountTrendingTChart.Series[0].Add(pdTime.ToArray(), pdReps.ToArray());
            pdCountTrendingTChart.Series[1].Add(pdTime.ToArray(), GetStatisticData(pdReps, pdTime, 1).ToArray());
            pdCountTrendingTChart.Series[2].Add(pdTime.ToArray(), GetStatisticData(pdReps, pdTime, 30).ToArray());
            AdjustAxisMinMax(pdCountTrendingTChart.Axes.Left);
        }

        private IEnumerable<float> GetStatisticData(List<float> data, List<DateTime> time, int days)
        {
            if(data != null && data.Count > 0)
            {
                int startIndex = 0;
                var currentDataSum = data[0];
                for(int i = 1; i < data.Count; i++)
                {
                    data[i] += currentDataSum;
                    while(!((time[i] - time[startIndex]).Days < days))
                        data[i] = data[i] - data[startIndex++];
                    currentDataSum = data[i];
                    data[i] /= (i - startIndex + 1);
                }
            }
            return data;
        }
    }
}
